﻿using System;
using System.Text;
using MugenInjection.Infrastructure;
using MugenInjection.Interface;

namespace MugenInjection.Exceptions
{
    /// <summary>
    /// The exception that is thrown when found cyclic bindings dependency.
    /// </summary>
#if !SILVERLIGHT
#if !NETFX_CORE
    [Serializable]
#endif
#endif
    public class CyclicDependencyException : Exception
    {
        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="CyclicDependencyException"/> class with a specified error message.
        /// </summary>
        /// <param name="bindingContext">The specified <see cref="IBindingContext"/>.</param>
        public CyclicDependencyException(IBindingContext bindingContext)
            : base(FormatErrorMessage(bindingContext))
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CyclicDependencyException"/> class with a specified error message.
        /// </summary>
        /// <param name="message">The message that describes the error. </param>
        public CyclicDependencyException(string message)
            : base(message)
        {
        }

        #endregion

        #region Methods

        private static string FormatErrorMessage(IBindingContext bindingContext)
        {
            var sb = new StringBuilder();
            sb.AppendLine("A cyclical dependency was detected between the constructors of two services.");
            sb.AppendLine(string.Format("Make sure that you have not declared a dependency for {0} on any implementations of the service.", InjectorUtilsInternal.FormatType(bindingContext.Service)));
            sb.AppendLine("Use custom implementation of ICycleDependencyBehavior to avoid cycle.");
            sb.AppendLine("The activation path:");
            sb.AppendLine(InjectorUtilsInternal.GetBuildPath(bindingContext));
            return sb.ToString();
        }

        #endregion

    }
}